package com.dingwen.treasure.file.generate.util;


import cn.hutool.core.io.IoUtil;
import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import freemarker.template.Template;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.annotation.Resource;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 功能说明：
 *
 * @author dingwen
 * @since 2019-04-29 17:52
 **/
@Slf4j
@Component
public class FreeMarkerUtil {

    @Resource
    private FreeMarkerConfigurer freeMarkerConfigurer;

    private static final String UTF_8 = String.valueOf(StandardCharsets.UTF_8);


    /**
     * 通过模版渲染得到pdf文件
     *
     * @param data         数据
     * @param templateName 模板名称
     * @return {@link ByteArrayOutputStream}
     */
    public ByteArrayOutputStream getPdfFile(Map<String, Object> data, String templateName) {
        try {
            ByteArrayInputStream byteArrayInputStream = renderToFile(data, templateName);
            return convertToPdf(byteArrayInputStream);
        } catch (Exception e) {
            log.error("PDF文件生成异常：{}", e.getMessage());
            return null;
        }
    }


    /**
     * 得到模板
     *
     * @param templateName 模板名称
     * @return {@link Template}
     * @throws Exception 异常
     */
    private Template getTemplate(String templateName) throws Exception {
        return freeMarkerConfigurer.getConfiguration().getTemplate(templateName, UTF_8);
    }

    /**
     * 渲染生成文件且转换为pdf
     *
     * @param data         数据
     * @param templateName 模板名称
     * @return {@link String}
     */
    private ByteArrayInputStream renderToFile(Map<String, Object> data, String templateName) throws Exception {
        Writer out = new StringWriter();
        getTemplate(templateName).process(data, out);
        out.flush();
        return IoUtil.toStream(out.toString().getBytes(UTF_8));
    }


    /**
     * 转换成pdf文件
     *
     * @param inputStream 原数据流
     * @return {@link ByteArrayOutputStream}
     * @throws Exception 异常
     */
    private ByteArrayOutputStream convertToPdf(InputStream inputStream) throws Exception {
        @Cleanup
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        Document doc = new Document(inputStream);
        doc.save(byteArrayOutputStream, SaveFormat.PDF);
        return byteArrayOutputStream;
    }

}
